package com.alan.learn.configuration;

import cn.hutool.json.JSONUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * Created by liufan
 * 2018/12/05
 */
@Aspect
@Component
public class LogConfig {

    private static Logger log = LoggerFactory.getLogger(LogConfig.class);

    /**
     * 日志打印
     * 打印所有的 controller 里的东西
     */
    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    //@Pointcut("execution( * com.alan.learn.*.*(..))")
    public void pointCat() {
    }


    @Before("pointCat()")
    public void befautcar(JoinPoint joinPoint) {
        //获取请求
        // 接收到请求，记录请求内容
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            String signature = joinPoint.getSignature().getName();
            log.error("接口地址：" + request.getRequestURI() + "方法名称：" + signature + "参数：" + Arrays.toString(joinPoint.getArgs()));
        } catch (Exception e) {
            log.error("拦截接口进入，出错：｛｝", e.getMessage());
        }
    }

    @AfterReturning(returning = "ret", pointcut = "pointCat()")
    public void doAfterReturning(JoinPoint joinPoint, Object ret) {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            // 处理完请求，返回内容(返回值太复杂时，打印的是物理存储空间的地址)
            String signature = joinPoint.getSignature().getName();
            log.error("接口地址：" + request.getRequestURI() + "方法名称：" + signature + "参数：" + Arrays.toString(joinPoint.getArgs()) + "返回值：" + JSONUtil.toJsonStr(ret));
        } catch (Exception e) {
            log.error("拦截接口出去，出错：｛｝", e.getMessage());
        }
    }

    @Around("pointCat()")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        long startTime = System.currentTimeMillis();
        // ob 为方法的返回值
        Object ob = pjp.proceed();
        log.info("耗时 : " + (System.currentTimeMillis() - startTime));
        return ob;
    }


}
